package com.qf.fmall2202.order.service.impl;

import com.github.wxpay.sdk.WXPayUtil;
import com.qf.fmall2202.exception.QFException;
import com.qf.fmall2202.order.entity.OrderItem;
import com.qf.fmall2202.order.entity.Orders;
import com.qf.fmall2202.order.mapper.OrdersMapper;
import com.qf.fmall2202.order.service.IOrderItemService;
import com.qf.fmall2202.order.service.IOrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.fmall2202.order.vo.AddOrderReturnVo;
import com.qf.fmall2202.product.entity.ProductSku;
import com.qf.fmall2202.product.service.IProductSkuService;
import com.qf.fmall2202.shopcart.entity.ShoppingCart;
import com.qf.fmall2202.shopcart.service.IShoppingCartService;
import com.qf.fmall2202.utils.OrderContans;
import com.qf.fmall2202.utils.WxpayUtils;
import com.sun.org.apache.regexp.internal.RE;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 订单  服务实现类
 * </p>
 *
 * @author lzh
 * @since 2022-11-09
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {

    @Autowired
    IShoppingCartService shoppingCartService;
    @Autowired
    IOrderItemService orderItemService;
    @Autowired
    IProductSkuService productSkuService;

    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized AddOrderReturnVo add(Orders orders, String cids) {
        //返回前端的数据存入到vo中
//
        //前端传来的数据
        //cids 是订单编号
        // "actualAmount": 2,  //实际支付总价格
        //	"orderRemark": "来电蒜",
        //	"payType": 1,
        //	"receiverAddress": "湖北 武汉 江夏区 光谷大道77号",
        //	"receiverMobile": "13030303300",
        //	"receiverName": "张三",
        //	"totalAmount": 2, //订单总价格
        //	"userId": "20"

        //1.先判断买的商品是否有库存，买的商品数量根据cids查 shopping_cart表
        //2.查出cart_num
        //再根据 shoping_cart 表中 sku_id，查询 product_sku表 的stock
        //比较 cart_num 是否小于  stock

        //根据userid
        //查询出几个sku 就写多少个item
        //item_id UUID
        //order_id UUID
        //product_id 从 shopping_cart取出 product_id

        //1.接收 前端传来的数据
        //2.根据前端传来数据的，写到orders的表中
        //3.支付成功后，（写到order中之后） 删除购物车数据 根据orderId

        //0.过滤cids中可能存在的#
        cids = cids.replaceAll("#","");

        //1.cids--->List<购物车对象(填充所有信息)，用于生成订单明细表（按照）>
        List<ShoppingCart> shoppingCartsList = shoppingCartService.listCids(cids);

        //3.验证库存量是否够用
        checkStockNum(shoppingCartsList);

        //2.保存订单主表信息  orders
        //List<ShoppingCart> ---> Stream<skuName> ---->String名字1，名字2
        String skuNames = shoppingCartsList
                .stream()
                .map(ShoppingCart::getSkuName)
                .collect(Collectors.joining());  //连接字符串

        orders.setUntitled(skuNames);

        orders.setStatus(OrderContans.ORDER_WAIT_TO_PAY);//设置订单为待支付
        orders.setDeleteStatus(OrderContans.ORDER_DEFAULT_DELETE_FLAG); //逻辑删除标记

        orders.setCreateTime(new Date());
        orders.setUpdateTime(new Date());

        this.save(orders);//保存订单对象后会自动化回填

        String orderId = orders.getOrderId();

        //3.保存订单明细表信息 order_item
        //List<ShoppingCart> --->  List<OrderItem>
        List<OrderItem> orderItemList = shoppingCartsList
                .stream()
                .map(cart -> {
                    OrderItem orderItem = new OrderItem();

                    orderItem.setOrderId(orderId);
                    //把cart对象中同名属性拷贝过来
                    BeanUtils.copyProperties(cart,orderItem);

                    orderItem.setBuyCounts(Integer.valueOf(cart.getCartNum()));
                    //钱
                    orderItem.setTotalAmount(new BigDecimal(cart.getSellPrice()).multiply(new BigDecimal(cart.getCartNum())));
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    try {
                        orderItem.setBasketDate(simpleDateFormat.parse(cart.getCartTime()));
                    } catch (ParseException e) {
                        e.printStackTrace();

                    }
                    orderItem.setBuyTime(new Date());
                    orderItem.setIsComment(0);

                    return orderItem;
                }).collect(Collectors.toList());
        orderItemService.saveBatch(orderItemList);
        //4.扣减库存
//        //批量更新--转换
//        //List<ShoppingCart>  ------>  List<ProductSku>
//        List<ProductSku> productSkuList = shoppingCartsList
//                .stream()
//                .map(shoppingCart -> {
//
//                    ProductSku productSku = new ProductSku();
//
//                    productSku.setSkuId(shoppingCart.getSkuId());
//                    productSku.setStock(Integer.valueOf(shoppingCart.getStock()-Integer.valueOf(shoppingCart.getCartNum())));
//
//                    return productSku;
//
//                }).collect(Collectors.toList());
//                productSkuService.updateBatchById(productSkuList);
//        subStock(shoppingCartsList);



        //5.清空对应的购物车信息
        shoppingCartService.removeBatchByIds(shoppingCartsList);

        //6.调用微信支付平台接口，获取支付的url

        String url = getWexinByUrl(orderId);
        AddOrderReturnVo addOrderReturnVo = new AddOrderReturnVo();
        addOrderReturnVo.setOrderId(orderId);
        addOrderReturnVo.setProductNames(skuNames);
        addOrderReturnVo.setPayUrl(url);

        return addOrderReturnVo;


    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String status(String orderId) throws Exception {
        //1.调用微信支付工具列查询订单状态
        String status = WxpayUtils.queryOrder(orderId);
        if (status != null && status.equals(OrderContans.PAY_OK)){

            //更改数据库中给到订单表的状态，时间戳
            Orders orders = new Orders();
            orders.setOrderId(orderId);
            orders.setStatus(OrderContans.PAY_OK_STATUS);
            orders.setPayTime(new Date());
            orders.setUpdateTime(new Date());
            this.updateById(orders);

            //返回前端需要的成功状态字符串
            return OrderContans.PAY_OK_STATUS;
        }
        return OrderContans.PAY_NOT_OK_STATUS;


    }

    /**
     * 扣减库存
     * @param shoppingCartsList
     */
    private void subStock(List<ShoppingCart> shoppingCartsList) {


    }

    private String getWexinByUrl(String orderId) throws Exception {
        String payUrl = WxpayUtils.getPayUrl(orderId);
        return payUrl;

    }

    /**
     * 检验库存先合并sku_id 相同的数据，先得到总的购买量，在进行库存比较
     * @param shoppingCartsList
     */
    private void checkStockNum(List<ShoppingCart> shoppingCartsList) {
        //按照sku_id进行分析分组蔡操作
        Map<String, List<ShoppingCart>> skuIdMap = shoppingCartsList.stream()
                .collect(Collectors.groupingBy(ShoppingCart::getSkuId));

        for (Map.Entry<String, List<ShoppingCart>> entry : skuIdMap.entrySet()) {

            String skuId = entry.getKey();
            List<ShoppingCart> value = entry.getValue();
            //库存剩余多少
            Integer skuRemoveStock = value.get(0).getStock(); //剩余的库存量量

            //合并之后总的库存
            Integer totalNum = value.stream().collect(Collectors.summingInt(cart -> Integer.valueOf(cart.getCartNum())));

            if (totalNum > skuRemoveStock){ //超过库存
                //超过库存,抛异常
                throw new QFException("商品库存不足");
            }

            //扣减库存
            //
            ProductSku productSku = new ProductSku();
            productSku.setSkuId(skuId);
            productSku.setStock(skuRemoveStock - totalNum);
            productSkuService.updateById(productSku);

        }
    }
}
